#ifndef __LOGSYS_H__
#define __LOGSYS_H__
#include"logger.hpp"
//日志系统:
//作用：将一条消息，进行格式化称为指定格式的字符串后，写入到指定位置
//日志要写入指定位置（标准输出，指定文件，滚动文件，。。。）
//日志系统需要支持将日志消息落地到不同的位置 --- 多落地方向
//日志写入指定位置，支持不同的写入方式（同步，异步）
//同步：业务线程自己负责日志的写入（流程简单，但是有可能会因为阻塞导致效率降低）
//异步：业务线程将日志放入缓冲区内存，让其他异步线程负责将日志写入指定位置
//日志输出以日志器为单位，支持多日志器（不同的项目组有不同的输出策略）
//日志器的管理

//模块划分:
//日志等级模块：枚举出日志分为多少个等级 --- 对不同的日志有不同等级标记 -- 以便于控制输出
//日志消息模块：封装一条日志所需的各种要素（时间，线程 ID，文件名，行号，日志等级，消息主体...）
//消息格式化模块：按照指定的格式，对于日志消息关键要素进行组织，最终得到一个指定格式的字符串
//[%d{%H:%M:%S}]%T[%t]%T[%p]%T[%c]%T%f:%l%T%m% n[12:38:45][12345678][FATAL][root]main.c:178 套接字创建失败....\n
//日志落地模块：负责对日志消息进行指定方向的写入输出
//日志器模块：对上边几个模块的整合
//日志限制输出等级，消息格式化模块对象， 日志落地模块对象
//同步日志器模块 --- 完成日志的同步输出功能
//异步日志器模块 --- 完成日志的异步输出功能
//异步线程模块：负责异步日志的实际落地输出功能
//单例的日志器管理模块：对日志进行全局的管理，以便于能够在项目的任何位置获取指定的日志器进行日志输出
//日志器生成用的是建造者模式
//日志落地模块 用工厂模式
//日志输出 使用宏来进行代理



// 全局接口设计
// 提供全局接口 & 宏函数，对日志系统接口进行使用便捷性优化
// 思想:
// 提供获取指定日志器的全局接口（避免用户自己操作单例对象）
// 使用宏函数对日志器的接口进行代理（代理模式）
// 提供宏函数，直接通过默认日志器进行日志的标准输出打印（不用获取日志器了）
namespace logsys {
    // 1. 提供获取指定日志器的全局接口（避免用户自己操作单例对象）
    // 根据名称获取日志器指针，通过LoggerManager单例获取
    Logger::ptr getLogger(const std::string &name) {
        return logsys::LoggerManager::getInstance().getLogger(name);
    }
    // 获取默认日志器指针，通过LoggerManager单例获取
    Logger::ptr rootLogger() {
        return logsys::LoggerManager::getInstance().rootLogger();
    }

    // 2. 使用宏函数对日志器的接口进行代理（代理模式）
    // 定义不同日志级别的宏函数，将文件路径、行号以及可变参数传递给对应的日志函数
    #define debug(fmt,...) debug(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
    #define info(fmt,...) info(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
    #define warn(fmt,...) warn(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
    #define error(fmt,...) error(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
    #define fatal(fmt,...) fatal(__FILE__, __LINE__, fmt, ##__VA_ARGS__)

    // 3. 提供宏函数，直接通过默认日志器进行日志的标准输出打印（不用获取日志器了）
    // 定义不同日志级别的宏函数，通过默认日志器进行日志输出
    #define DEBUG(fmt,...) logsys::rootLogger()->debug(fmt, ##__VA_ARGS__)
    #define INFO(fmt,...) logsys::rootLogger()->info(fmt, ##__VA_ARGS__)
    #define WARN(fmt,...) logsys::rootLogger()->warn(fmt, ##__VA_ARGS__)
    #define ERROR(fmt,...) logsys::rootLogger()->error(fmt, ##__VA_ARGS__)
    #define FATAL(fmt,...) logsys::rootLogger()->fatal(fmt, ##__VA_ARGS__)
}
#endif